/*
 * Copyright (C) 2014-present, Wei Chou (weichou2010@gmail.com)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.wei.c.widget;

import android.annotation.SuppressLint;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.widget.LinearLayout;

/**
 * @author 周伟 Wei Chou(weichou2010@gmail.com)
 */
public class StretchFirstChildLayout extends LinearLayout {
    protected static final String LOG_TAG = StretchFirstChildLayout.class.getSimpleName();
    protected static final boolean LOG = false;

    public StretchFirstChildLayout(Context context) {
        super(context);
    }

    public StretchFirstChildLayout(Context context, AttributeSet attr) {
        super(context, attr);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        if (getChildCount() < 2) {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            return;
        }
        //是否必然经过EXACTLY这种测量模式？暂时未知。当前应用不影响
        if (MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.EXACTLY) {
            int orientation = getOrientation();
            if (orientation == HORIZONTAL) {
                reMeasureHorizontal(widthMeasureSpec, heightMeasureSpec);
            } else if (orientation == VERTICAL) {
                reMeasureVertical(widthMeasureSpec, heightMeasureSpec);
            }
        } else {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        }
    }

    @SuppressLint("WrongCall")
    protected void reMeasureHorizontal(int widthMeasureSpec, int heightMeasureSpec) {
        ///////////////////////////TODO 暂未实现, 待续//////////////////////////////////
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        ////////////////////////////////////////////////////////////////////////
    }

    @SuppressLint("WrongCall")
    protected void reMeasureVertical(int widthMeasureSpec, int heightMeasureSpec) {
        if (LOG) Log.i(LOG_TAG, "reMeasureVertical---------------------------");
        int specMode = MeasureSpec.getMode(heightMeasureSpec);
        int specSize = MeasureSpec.getSize(heightMeasureSpec);

        int heightSumExceptFirst = 0;
        int heightSumFirst = 0;
        //肯定是大于等于2的，否则不会进入本方法
        final int childCount = getChildCount();
        final View firstChild = getChildAt(0);
        final int[] unspecifiedHeight = new int[childCount];

        for (int j = 0; j < 2; j++) {
            switch(j) {
            case 0:
                //这种方式可以测量实际想要的大小，但是如果只进行这种测量，当layout_gravity="bottom"时组件会从底部向上排列。
                specMode = MeasureSpec.UNSPECIFIED;
                break;
            case 1:
                specMode = MeasureSpec.EXACTLY;
                break;
            }
            super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(specSize, specMode));
            switch(specMode) {
            case MeasureSpec.EXACTLY:
                if (LOG) Log.i(LOG_TAG, "VERTICAL: EXACTLY, specSize=" + specSize);

                final LayoutParams firstLp = (LayoutParams)firstChild.getLayoutParams();
                final int firstMH = firstChild.getMeasuredHeight();
                heightSumFirst = firstMH > heightSumFirst ? firstMH : heightSumFirst;
                heightSumFirst += firstLp.topMargin + firstLp.bottomMargin;
                if (LOG) {
                    Log.i(LOG_TAG, "child[" + 0 + "]measuredWidth:" + firstChild.getMeasuredWidth() + ", measuredHeight:" + firstMH);
                    for (int i = 1; i < childCount; i++) {
                        final View child = getChildAt(i);
                        Log.i(LOG_TAG, "child[" + i + "]measuredWidth:" + child.getMeasuredWidth() + ", measuredHeight:" + child.getMeasuredHeight());
                    }
                }
                break;
            case MeasureSpec.AT_MOST:
                if (LOG) {
                    Log.i(LOG_TAG, "VERTICAL: AT_MOST, specSize=" + specSize);
                    for (int i = 0; i < childCount; i++) {
                        final View child = getChildAt(i);
                        Log.i(LOG_TAG, "child[" + i + "]measuredWidth:" + child.getMeasuredWidth() + ", measuredHeight:" + child.getMeasuredHeight());
                    }
                }
                break;
            case MeasureSpec.UNSPECIFIED:
                if (LOG) Log.i(LOG_TAG, "VERTICAL: UNSPECIFIED, specSize=" + specSize);

                int measuredHeight = firstChild.getMeasuredHeight();
                unspecifiedHeight[0] = measuredHeight;
                //后面在case MeasureSpec.EXACTLY中还有一次计算，这里省略margins的计算
                heightSumFirst = measuredHeight;
                if (LOG) Log.i(LOG_TAG, "child[" + 0 + "]measuredWidth:" + firstChild.getMeasuredWidth() + ", measuredHeight:" + measuredHeight);

                for (int i = 1; i < childCount; ++i) {
                    final View child = getChildAt(i);
                    measuredHeight = child.getMeasuredHeight();
                    unspecifiedHeight[i] = measuredHeight;
                    if(child.getVisibility() != View.GONE) {
                        final LayoutParams lp = (LayoutParams)child.getLayoutParams();
                        heightSumExceptFirst += lp.topMargin + measuredHeight + lp.bottomMargin;
                    }
                    if (LOG) Log.i(LOG_TAG, "child[" + i + "]measuredWidth:" + child.getMeasuredWidth() + ", measuredHeight:" + measuredHeight);
                }
                /*View lastChild = getChildAt(childCount - 1);
				//这样是错误的，这个时候还没有requestlayout,获取到的值是上次布局的时候得到的值
				lastChildBottom = lastChild.getBottom();*/
                break;
            }
        }
        final int measuredHeight = getMeasuredHeight();
        final int parentHeightPadding = getPaddingTop() + getPaddingBottom();
        final int delta = heightSumExceptFirst + heightSumFirst - (measuredHeight - parentHeightPadding);
        if (LOG) Log.i(LOG_TAG, ">>measuredHeight=" + measuredHeight + ", parentHeightPadding=" + parentHeightPadding + ", heightSum=" + (heightSumExceptFirst + heightSumFirst));

        if(delta > 0) {	//说明有组件出界
            if (LOG) Log.i(LOG_TAG, ">>delta=" + delta);

            for (int i = 1; i < childCount; ++i) {
                final View child = getChildAt(i);
                final int childMeasWidth = MeasureSpec.makeMeasureSpec(child.getMeasuredWidth(), MeasureSpec.EXACTLY);
                //对于EXACTLY，mMeasuredHeight就是指定的值，详见源码
                final int childMeasHeight = MeasureSpec.makeMeasureSpec(unspecifiedHeight[i], MeasureSpec.EXACTLY);
                child.measure(childMeasWidth, childMeasHeight);
            }
            final LayoutParams firstLp = (LayoutParams)firstChild.getLayoutParams();
            final int childMeasWidth = MeasureSpec.makeMeasureSpec(firstChild.getMeasuredWidth(), MeasureSpec.EXACTLY);
            final int childMeasHeight = MeasureSpec.makeMeasureSpec(measuredHeight - parentHeightPadding - heightSumExceptFirst - firstLp.topMargin - firstLp.bottomMargin, MeasureSpec.EXACTLY);
            firstChild.measure(childMeasWidth, childMeasHeight);
        }
    }
}
